from django.shortcuts import render
from django.views import View
from meiduo_mall.libs.captcha.captcha import captcha
from django.http import HttpResponse,JsonResponse
from django_redis import get_redis_connection
from meiduo_mall.libs.yuntongxun.ccp_sms import CCP
from celery_tasks.sms.tasks import send_sms
import random

class ImageCodeView(View):
    def get(self,request,uuid):
        # 1.调取captcha工具类，生成图形验证码
        text,image = captcha.generate_captcha()
        print('图形验证码:',text)
        # 2. 连接redis数据库，获取连接对象
        redis_conn = get_redis_connection('verify_code')
        # 3. 通过连接对象，使用setex函数，把数据保存到redis数据库中
        redis_conn.setex('img_%s' %uuid, 300,text)
        # 4. 返回图片
        return HttpResponse(image,content_type='image/jpg')


class SMSCodeView(View):
    def get(self,request,mobile):
        # 1. 获取请求参数
        # 获取图形验证码参数
        image_code= request.GET.get('image_code')
        # 获取图形验证码id
        image_code_id = request.GET.get('image_code_id')
        # 2. 校验参数
        if not all([image_code,image_code_id]):

            return JsonResponse({
                'code':400,
                'errmsg':'请求参数不存在！！！'
            })
        # 3.连接数据库
        redis_conn = get_redis_connection('verify_code')
        # 4. 从数据库获取验证码信息
        imag_code_from_redis = redis_conn.get('img_%s' %image_code_id)
        # 判断验证码信息是否过期
        if not imag_code_from_redis:
            # 图形验证码过期
            return JsonResponse({
                'code': 400,
                'errmsg': '图形验证码过期！'
            })

        # 5. 进行参数对比
        # 从数据库获取的信息是字节型字符串，需要进行转换
        # imag_code_server = imag_code_server.decode()
        # 进行参数对比
        if image_code.lower() != imag_code_from_redis.decode().lower():
            return JsonResponse({
                'code':400,
                'errmsg':'图形验证码错误！！！'
            })

        # 为了图形验证码被频繁验证。原则上一个图形码只能验证一次
        # 解决方法：从redis数据库中读取一次就删除
        redis_conn.delete('img_%s' %image_code_id)


        # 判断用户是否发送过短信
        flag = redis_conn.get('sms_flag_%s'%mobile)
        if flag:
            return JsonResponse({
                'code':400,
                'errmsg':'请勿重复发送短信！！！'
            })

        # 6. 生成6位数随机码
        sms_code = '%06d' %random.randint(0,999999)
        print('手机验证码：',sms_code)
        # 7. 保存验证码到数据库中
            # 设置管道
        p = redis_conn.pipeline()
        try:
            p.setex('sms_%s' %mobile,300,sms_code)
            # 为了避免频繁发送短信，设置一个标志位来标志用户已经发送过短信
            p.setex('sms_flag_%s'%mobile,60,1)
            # 通过管道批量执行redis指令
            p.execute()
        except Exception as e:
            return JsonResponse({
                'code':400,
                'errmsg':'访问数据库失败！'
            })
        # 8. 发生短信验证码
        # 短信模板
        # 设置验证码的有效时间为5分钟
        # CCP().send_template_sms(mobile,[sms_code,5],'-1')
        send_sms.delay(mobile, sms_code)

        # 9. 返回响应结果
        return JsonResponse({
            'code':0,
            'errmsg':'短信发送成功!!!'
        })

    # def get(self, request, mobile):
    #     # 1、验证前端数据(校验图形验证码)
    #     image_code = request.GET.get('image_code')
    #     image_code_id = request.GET.get('image_code_id')
    #
    #     # 1.1 如果image_code或者image_code_id某一个不存在，则参数错误
    #     if not all([image_code, image_code_id]):
    #         return JsonResponse({
    #             'code': 400,
    #             'errmsg': '参数错误！'
    #         })
    #
    #     # 1.2 读取redis中的图形验证码
    #     conn = get_redis_connection('verify_code')
    #     # redis返回的数据，如果没有则None，如果有返回的是字符串的字节形式b'CFGR' --> b'CFGR'.decode() --> 'CFGR'
    #     image_code_from_redis = conn.get('img_%s' % image_code_id)
    #     if not image_code_from_redis:
    #         # 图形验证码过期
    #         return JsonResponse({
    #             'code': 400,
    #             'errmsg': '图形验证码过期！'
    #         })
    #     if image_code.lower() != image_code_from_redis.decode().lower():
    #         # 用户输入错误
    #         return JsonResponse({
    #             'code': 400,
    #             'errmsg': '验证码输入有误！'
    #         })
    #
    #     # 为了防止图形验证码被频繁验证，原则上一个图形验证码只能使用一次
    #     # 解决方案：从redis中读取，就直接销毁
    #     conn.delete('img_%s' % image_code_id)
    #
    #     # 判断60秒之内是否发送过短信
    #     flag = conn.get("sms_flag_%s" % mobile)
    #     if flag:
    #         return JsonResponse({
    #             'code': 400,
    #             'errmsg': '请勿重复发送短信！'
    #         })
    #
    #     # 2、调用云通讯发送短信
    #     # 2.1 生成一个随机的短信验证码(6位数)
    #     sms_code = "%06d" % random.randint(0, 999999)
    #     print("手机验证码：", sms_code)
    #     # 2.2 短信验证码存储进redis，设计key：sms_{手机号}
    #     p = conn.pipeline()  # 获取一个管道对象
    #     try:
    #         p.setex("sms_%s" % mobile, 300, sms_code)
    #         # 添加标志位
    #         p.setex("sms_flag_%s" % mobile, 60, '-1')
    #
    #         p.execute()  # 通过管道批量执行redis指令
    #     except Exception as e:
    #         # logger.info(e)
    #         return JsonResponse({
    #             'code': 400,
    #             'errmsg': 'redis数据库访问失败！'
    #         })
    #
    #     # 2.3 调用云通讯发送短信
    #     # CCP().send_template_sms(mobile, [sms_code, 5], 1)
    #     # 2.3 发布"发送短信"任务，交给异步程序去执行，此处不会阻塞
    #     send_sms.delay(mobile, sms_code)
    #
    #     # 3、构建响应返回
    #     return JsonResponse({
    #         'code': 0,
    #         'errmsg': 'ok'
    #     })

